/*
 $Id$

 Copyright (C) 2006-2007 by David Cotton

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
 Foundation; either version 2 of the License, or (at your option) any later
 version.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
 Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package fr.free.jchecs.core;

import static fr.free.jchecs.core.PieceType.BISHOP;
import static fr.free.jchecs.core.PieceType.KING;
import static fr.free.jchecs.core.PieceType.KNIGHT;
import static fr.free.jchecs.core.PieceType.PAWN;
import static fr.free.jchecs.core.PieceType.QUEEN;
import static fr.free.jchecs.core.PieceType.ROOK;

import java.util.HashMap;
import java.util.Map;

/**
 * Enumeration of parts.
 * <p>
 * Instances of this class are <b>immutable singleton</b>: class safe overlooked
 * threads and allowing direct comparisons on the object references.
 * </p>
 * 
 * @author David Cotton
 */
public enum Piece {
	/** Black bishop. */
	BLACK_BISHOP('b', false, BISHOP),

	/** Black king. */
	BLACK_KING('k', false, KING),

	/** Black knight. */
	BLACK_KNIGHT('n', false, KNIGHT),

	/** Black pawn. */
	BLACK_PAWN('p', false, PAWN),

	/** Black queen. */
	BLACK_QUEEN('q', false, QUEEN),

	/** Black rook. */
	BLACK_ROOK('r', false, ROOK),

	/** White bishop. */
	WHITE_BISHOP('B', true, BISHOP),

	/** White king. */
	WHITE_KING('K', true, KING),

	/** White knight. */
	WHITE_KNIGHT('N', true, KNIGHT),

	/** White pawn. */
	WHITE_PAWN('P', true, PAWN),

	/** White queen */
	WHITE_QUEEN('Q', true, QUEEN),

	/** White rook. */
	WHITE_ROOK('R', true, ROOK);

	/** Transpositions letters FEN / parts. */
	private static final Map<Character, Piece> FEN_TO_PIECE = new HashMap<Character, Piece>();
	static {
		for (final Piece p : values()) {
			FEN_TO_PIECE.put(Character.valueOf(p.getFENLetter()), p);
		}
	}

	/** Character identifying the piece in FEN notation. */
	private final char _fenLetter;

	/** Flag set to true if the room is white. */
	private final boolean _white;

	/** Type of room. */
	private final PieceType _type;

	/**
	 * Instantiate a share description.
	 * 
	 * @param pLettre
	 *            FEN character identifier.
	 * @param pBlanc
	 *            Flag to true for a white room.
	 * @param pType
	 *            Type of the room.
	 */
	private Piece(final char pLettre, final boolean pBlanc,
			final PieceType pType) {
		assert pType != null;

		_fenLetter = pLettre;
		_white = pBlanc;
		_type = pType;
	}

	/**
	 * Returns the character FEN identifying the room.
	 * 
	 * @return FEN character.
	 */
	public char getFENLetter() {
		return _fenLetter;
	}

	/**
	 * Returns the type of room.
	 * 
	 * @return Type of the room.
	 */
	public PieceType getType() {
		assert _type != null;
		return _type;
	}

	/**
	 * Returns true if the room is white.
	 * 
	 * @return True if the room is white.
	 */
	public boolean isWhite() {
		return _white;
	}

	/**
	 * Reference the instance of a character piece is FEN.
	 * 
	 * @param pLettre
	 *            FEN character identifier.
	 * @return Corresponding piece.
	 */
	public static Piece valueOf(final char pLettre) {
		return FEN_TO_PIECE.get(Character.valueOf(pLettre));
	}
}
